package ro.ubbcluj.cs.damate.managers.administration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import ro.ubbcluj.cs.damate.persistence.entities.Group;
import ro.ubbcluj.cs.damate.persistence.entities.Role;
import ro.ubbcluj.cs.damate.services.GroupService;
import ro.ubbcluj.cs.damate.services.RoleService;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Lóránd Fazakas (lfazakas)
 *         Date: 2013.03.25.
 *         Time: 22:38
 */
@Component
@Scope("view")
public class GroupManager implements Serializable {

    @Autowired
    private AdministrationView administrationView;

    @Autowired
    private GroupService groupService;

    @Autowired
    private RoleService roleService;

    private List<Group> groups;
    private List<Group> filteredGroups;

    private String newGroupName;
    private List<UserRoleMapper> roles;

    private Group modifiedGroup;

    private void clean() {
        this.groups = null;
        this.filteredGroups = null;
        this.newGroupName = null;
        this.roles = null;
        this.modifiedGroup = null;
    }

    public void save() {
        Group newGroup = new Group();
        newGroup.setGroupName(newGroupName);
        newGroup.setRoles(getRolesToAssign(roles));
        groupService.create(newGroup);
        clean();
        administrationView.switchPanel(AdministrationView.AdminPanel.LIST_USER_GROUPS.name());
    }

    public void update() {
        modifiedGroup.setRoles(getRolesToAssign(roles));
        groupService.update(modifiedGroup);
        clean();
        administrationView.switchPanel(AdministrationView.AdminPanel.LIST_USER_GROUPS.name());
    }

    private List<Role> getRolesToAssign(List<UserRoleMapper> roleMappers) {
        List<Role> rolesToAssign = new ArrayList<Role>();
        for(UserRoleMapper role : roleMappers) {
            if (role.isChecked()) {
                Role assignedRole = roleService.findRoleByName(role.getRole().name());
                if (assignedRole != null) {
                    rolesToAssign.add(assignedRole);
                }
            }
        }
        return rolesToAssign;
    }

    public void edit(Group group) {
        this.modifiedGroup = group;
        for(UserRoleMapper roleMapper : getRoles()) {
            for(Role assignedRole : modifiedGroup.getRoles()) {
                if (roleMapper.getRole().name().equals(assignedRole.getRoleName())) {
                    roleMapper.setChecked(true);
                    break;
                }
            }
        }
        administrationView.switchPanel(AdministrationView.AdminPanel.NEW_USER_GROUP.name());
    }

    public void delete(Group group) {
        groupService.delete(group);
        clean();
    }

    public void cancel() {
        clean();
        administrationView.switchPanel(AdministrationView.AdminPanel.DESCRIPTION.name());
    }

    public void openPanel(String panelName) {
        clean();
        administrationView.switchPanel(panelName);
    }

    public List<Group> getGroups() {
        if (groups == null) {
            this.groups = groupService.findAll();
        }
        return groups;
    }

    public void setGroups(List<Group> groups) {
        this.groups = groups;
    }

    public String getRoles(Group group) {
        StringBuilder roles = new StringBuilder();
        for(Role role : group.getRoles()) {
            roles.append(role.getRoleName()+", ");
        }
        return roles.length() > 0 ? roles.toString().substring(0, roles.length()-2) : "no roles";
    }

    public List<Group> getFilteredGroups() {
        return filteredGroups;
    }

    public void setFilteredGroups(List<Group> filteredGroups) {
        this.filteredGroups = filteredGroups;
    }

    public String getNewGroupName() {
        return newGroupName;
    }

    public void setNewGroupName(String newGroupName) {
        this.newGroupName = newGroupName;
    }

    public List<UserRoleMapper> getRoles() {
        if (roles == null) {
            roles = new ArrayList<UserRoleMapper>();
            for(UserRole role : UserRole.values()) {
                roles.add(new UserRoleMapper(role));
            }
        }
        return roles;
    }

    public void setRoles(List<UserRoleMapper> roles) {
        this.roles = roles;
    }

    public Group getModifiedGroup() {
        return modifiedGroup;
    }

    public void setModifiedGroup(Group modifiedGroup) {
        this.modifiedGroup = modifiedGroup;
    }
}
